package com.eagle.support.common;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.kinstalk.voip.sdk.EngineSdkCallState;
import com.kinstalk.voip.sdk.EngineSdkSessionDirection;
import com.kinstalk.voip.sdk.EngineSdkVideoChannelState;
import com.kinstalk.voip.sdk.api.WeaverService;
import com.kinstalk.voip.sdk.interfaces.WeaverCallStateListener;
import com.kinstalk.voip.sdk.interfaces.WeaverMessageListener;
import com.kinstalk.voip.sdk.interfaces.WeaverRequestListener;
import com.kinstalk.voip.sdk.logic.sip.SipLogicApi;
import com.kinstalk.voip.sdk.logic.sip.aidl.model.CallInfo;
import com.kinstalk.voip.sdk.logic.sip.utility.MediaManager;
import com.kinstalk.voip.sdk.model.WeaverRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 * Created by shaoyun on 2016/12/23.
 */

public class CallStatusManager implements WeaverCallStateListener, WeaverRequestListener, WeaverMessageListener {
    public static final String TAG = "cim";

    private static EventHandler mEventHandler;
    private static CallStatusManager gInstance;

    private boolean mStarCallIsVideoCall = false;
    private boolean mSelfAnswerCallIsVideoCall = false;
    private boolean mFinalCallIsVideoCall = false;
    private boolean mIsInCalling = false;
    private boolean mWaitDown2Audio = false;

    public static CallStatusManager getInstance() {
        if (gInstance == null) {
            gInstance = new CallStatusManager();
        }
        return gInstance;
    }

    private CallStatusManager() {

    }

    public void setEventHandler(EventHandler eventHandler) {
        mEventHandler = eventHandler;
    }

    @Override
    public void onCallStateChange(CallInfo call, int state) {
        Log.e(TAG, "onCallStateChange:" + EngineSdkCallState.swigToEnum(state) + "-" + (mEventHandler == null));

        switch (EngineSdkCallState.swigToEnum(state)) {
            case ES_STATE_ON_CALL_CALLING_OUT:
                onCallingOut(call);
                break;
            case ES_STATE_ON_CALL_RINGBACK_TONE:
                onRingBackTone(call);
                break;
            case ES_STATE_ON_CALL_INCOMMING_CALL:
                onIncoming(call);
                break;
            case ES_STATE_ON_CALL_ANSWERING_CALL:
                onAnsweringCall(call);
                break;
            case ES_STATE_ON_CALL_IN_ACTIVE_SESSION:
                onInActiveSession(call);
                break;
            case ES_STATE_ON_CALL_CALL_ENDED:
                onCallEnded(call);
                break;
            case ES_STATE_ON_CALL_CALL_ENDING:
                onCallEnding(call);
                break;
            default:
                break;
        }

        if (mEventHandler != null) {
            Handler handler = mEventHandler.getHandler();
            handler.sendMessage(handler.obtainMessage(EventHandler.KEY_CALL_STATE, state, 0, call));
        }
    }

    private void onCallEnding(CallInfo call) {
        mStarCallIsVideoCall = false;
        mSelfAnswerCallIsVideoCall = false;
        mFinalCallIsVideoCall = false;
        esStateOnCallCallEnded(call);
    }

    private void onIncoming(CallInfo call) {
        onStarCallType(call.getCallConfiguration().isMainVideoEnabled());
        onStarCallType(call.getCallConfiguration().isMainVideoEnabled());
        if (mStarCallIsVideoCall
                && call.mainVideoReceivingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED
                && call.mainVideoTransmitingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED) {
            onDowntoAudio();
        }
        esStateOnCallIncommingCall(call);
    }

    private void esStateOnCallIncommingCall(CallInfo call) {
        SipLogicApi.playRingtone(this, MediaManager.RingtoneType.INCOMING);
    }

    private void onRingBackTone(CallInfo call) {
        if (mWaitDown2Audio) {
            mWaitDown2Audio = false;
            WeaverService.getInstance().dispatchRequest(SipLogicApi.setDown2Audio(true, null));
        }
        if (mStarCallIsVideoCall && call.mainVideoReceivingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED
                && call.mainVideoTransmitingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED) {
            onDowntoAudio();
        }
        esStateOnCallRingbackTone(call);
    }

    private void onAnsweringCall(CallInfo call) {
        mSelfAnswerCallIsVideoCall = call.getCallConfiguration().isMainVideoEnabled();
        eSStateOnCallAnsweringCall(call);
    }

    private void onInActiveSession(CallInfo call) {
        if (call.mainVideoReceivingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_ACTIVE
                && call.mainVideoTransmitingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_ACTIVE) {
            mFinalCallIsVideoCall = true;
            if (mSelfAnswerCallIsVideoCall || mStarCallIsVideoCall) {
                Log.e(TAG, "Call Type:" + "video call， Video answer:" + "\n" +
                        call.getSessionId() + "\n" +
                        call.getCallConfiguration().getChannelID() + "\n" +
                        call.getCallConfiguration().getRemoteAccountId() + "\n" +
                        call.getCallConfiguration().getCallDirection());
                onAnswerCallType(true); //视频呼叫，视频应答。
            }
        } else {
            mFinalCallIsVideoCall = false;
            if (call.mainVideoReceivingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_CREATED
                    && call.mainVideoTransmitingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_CREATED) {
                if (!mSelfAnswerCallIsVideoCall || mStarCallIsVideoCall) {
                    Log.e(TAG, "Call Type:" + "video call， audio answer");
                    onAnswerCallType(false); //视频（音频）呼叫，音频应答。
                }
            } else if (call.mainVideoReceivingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED
                    && call.mainVideoTransmitingState == EngineSdkVideoChannelState.ES_STATE_ON_VIDEO_CHANNEL_DESTROYED) {
                if (!mSelfAnswerCallIsVideoCall && mStarCallIsVideoCall) {
                    Log.e(TAG, "Call Type:" + "video call， down2audio， audio answer");
                    onAnswerCallType(false); //视频呼叫，中间切换音频，音频应答。
                } else { //点击切换音频和视频应答同时进行。
                    Log.e(TAG, "Call Type:" + "Other State");
                    //其他状态，需要通过call的setVideoPaused和RequestRemoteVideoPaused来更新状态。
                    onAnswerCallType(true);//视频呼叫，切换和应答同时点击。
                }
            }

        }

        onFinalCallStatus(mFinalCallIsVideoCall);
        esStateOnCallInActiveSession(call);
    }

    private void onCallEnded(CallInfo call) {
        mStarCallIsVideoCall = false;
        mSelfAnswerCallIsVideoCall = false;
        mFinalCallIsVideoCall = false;
        esStateOnCallCallEnded(call);
    }

    @Override
    public void onRecvRingingMsg(String msg) {
        Log.e(TAG, "msg: " + msg);
        Handler handler = mEventHandler.getHandler();
        handler.sendMessage(handler.obtainMessage(EventHandler.KEY_RING_MESSAGE, 0, 0, msg));
    }

    private void eSStateOnCallAnsweringCall(CallInfo call) {
        if (call.getCallConfiguration().getCallDirection() == EngineSdkSessionDirection.INCOMMING) {
            // 通话接通
            SipLogicApi.stopPlaying(this);
            SipLogicApi.entryInCallState(this);
            mIsInCalling = true;
            SipLogicApi.setInCallingMode(this, MediaManager.InCallMode.AUDIO_VIDEO);
            SipLogicApi.operateSystemAudio(this);
            int state = 0;
            if (state == 1) {
                SipLogicApi.setEarphoneConnected(this, true);
            } else {
                SipLogicApi.setHandfree(this, true);
            }
        }
    }

    private void esStateOnCallCallEnded(CallInfo call) {
        if (call != null && call.getCallConfiguration() != null) {
            if (call.getCallConfiguration().getCallDirection() == EngineSdkSessionDirection.INCOMMING) {
                if (mIsInCalling) {
                    mIsInCalling = false;
                    SipLogicApi.leaveInCallState(this);
                }
            } else if (call.getCallConfiguration().getCallDirection() == EngineSdkSessionDirection.OUTGOING) {
                if (mIsInCalling) {
                    mIsInCalling = false;
                    SipLogicApi.leaveInCallState(this);
                }
            }
        }
        SipLogicApi.stopPlaying(this);
    }

    private void esStateOnCallInActiveSession(CallInfo call) {
        if (call.getCallConfiguration().getCallDirection() == EngineSdkSessionDirection.OUTGOING) {
            // 通话接通
            SipLogicApi.stopPlaying(this);
            SipLogicApi.entryInCallState(this);
            mIsInCalling = true;
            SipLogicApi.setInCallingMode(this, MediaManager.InCallMode.AUDIO_VIDEO);
            int state = 0;
            if (state == 1) {
                SipLogicApi.setEarphoneConnected(this, true);
            } else {
                SipLogicApi.setHandfree(this, true);
            }

            SipLogicApi.operateSystemAudio(this);
        }
    }

    @Override
    public void onRequestFinshed(WeaverRequest weaverRequest) {

    }

    private void esStateOnCallRingbackTone(CallInfo call) {
//        SipLogicApi.playRingtone(this, MediaManager.RingtoneType.OUTGOING);
    }

    private void onCallingOut(CallInfo call) {
        onStarCallType(call.getCallConfiguration().isMainVideoEnabled());
    }

    private void onStarCallType(boolean flag) {
        mStarCallIsVideoCall = flag;
        if (flag) {
            Log.e(TAG, "Call Type" + "开启视频通话");
        } else {
            Log.e(TAG, "Call Type" + "开启音频通话");
        }
    }

    private void onAnswerCallType(boolean flag) {
        if (flag) {
            Log.e(TAG, "Call Type" + "视频应答");
        } else {
            Log.e(TAG, "Call Type" + "音频应答");
        }
    }

    private void onFinalCallStatus(boolean flag) {
        if (flag) {
            Log.e(TAG, "Call Type" + "建立视频通话");
        } else {
            Log.e(TAG, "Call Type" + "建立音频通话");
        }
    }

    private void onDowntoAudio() {
        Log.e(TAG, "Call Type" + "切换到音频");
    }

    @Override
    public void onMessage(int msgId, String msgGlobalId, String sender, String msgContent, String mimeType) {
        Log.e(TAG, "onMessage:" + "\n" +
                "msgId=" + msgId + "\n" +
                "msgGlobalId=" + msgGlobalId + "\n" +
                "sender=" + sender + "\n" +
                "msgContent=" + msgContent + "\n" +
                "mimeType=" + mimeType);

        if (null == msgContent) {
            return;
        }

        try {
            JSONTokener jsonParser = new JSONTokener(msgContent);
            JSONObject conference = (JSONObject) jsonParser.nextValue();
            if (!conference.isNull("conference")) {
                JSONObject roomidObj = conference.getJSONObject("conference");
                if (roomidObj.isNull("notify")) {
                    Log.e(TAG, "receive master invite");
                    String roomid = roomidObj.getString("RoomId");
                    Log.e(TAG, "conference room id is " + roomid);
                    Bundle bd = new Bundle();
                    bd.putString("roomid", roomid);
                    bd.putString("sender", sender);
                    Handler handler = mEventHandler.getHandler();
                    Message a = handler.obtainMessage(EventHandler.KEY_MESSAGE_NOTIFY, EventHandler.KEY_GOT_INVITE_CONF_ROOMID, 0, 0);
                    a.setData(bd);
                    handler.sendMessage(a);
                } else {
                    Log.e(TAG, "receive notify");
                    if (!roomidObj.isNull("ByeCid")) {
                        Log.e(TAG, "receive bye notify");
                        String byeCid = roomidObj.getString("ByeCid");
                        Handler handler = mEventHandler.getHandler();
                        handler.sendMessage(handler.obtainMessage(EventHandler.KEY_CONFERENCE_CHANNELID_NOTIFY, EventHandler.KEY_BYE_CID, 0, byeCid));
                    } else {
                        Log.e(TAG, "receive add notify");
                        JSONArray notify = roomidObj.getJSONArray("notify");
                        if (notify != null) {
                            for (int i = 0; i < notify.length(); i++) {
                                JSONObject obj = notify.getJSONObject(i);
                                Bundle bd = new Bundle();
                                bd.putString("channelid", obj.getString("channelid"));
                                bd.putString("uid", obj.getString("uid"));
                                Handler handler = mEventHandler.getHandler();
                                Message a = handler.obtainMessage(EventHandler.KEY_CONFERENCE_CHANNELID_NOTIFY, EventHandler.KEY_ADD_CID, 0, 0);
                                a.setData(bd);
                                handler.sendMessage(a);
                            }
                        }
                    }
                }

            } else if (!conference.isNull("live")) {
                JSONObject roomId = conference.getJSONObject("live");
                if (!roomId.isNull("ByeCid")) {
                    WeaverService.getInstance().dispatchRequest(SipLogicApi.stopPlaying(this));
                    WeaverService.getInstance().dispatchRequest(SipLogicApi.sipEndCall(0, null));

                    Log.e(TAG, "receive master bye");
                    Handler handler = mEventHandler.getHandler();
                    handler.sendMessage(handler.obtainMessage(EventHandler.KEY_MESSAGE_NOTIFY, EventHandler.KEY_LIVE_END, 0, null));
                }
            }
        } catch (JSONException e) {
            Log.e(TAG, "JSONException" + e.getMessage().toString());
            return;
        }
    }

    @Override
    public void onMessageSentResult(int msgId, String msgGlobalId, String msgSentTime, String remote_number, boolean isSuccess, String msgContent, String mimeType, String reason) {
        if ("live_".equals(remote_number)) {
            try {
                JSONTokener jsonParser = new JSONTokener(msgContent);
                JSONObject conferenceObj = (JSONObject) jsonParser.nextValue();
                JSONObject roomidObj = conferenceObj.getJSONObject("conference");
                String roomid = String.valueOf(roomidObj.getInt("RoomId"));
                Log.e(TAG, "onMessageSentResult live room id is: " + roomid + "-" + msgContent);
                Handler handler = mEventHandler.getHandler();
                handler.sendMessage(handler.obtainMessage(EventHandler.KEY_MESSAGE_RESULT, EventHandler.KEY_GOT_LIVE_ROOMID, 0, roomid));
            } catch (JSONException e) {
                Log.e(TAG, "onMessageSentResult live_: " + e.getMessage().toString());
                e.printStackTrace();
            }
        } else if ("mconf_".equals(remote_number)) {
            try {
                JSONTokener jsonParser = new JSONTokener(msgContent);
                JSONObject conferenceObj = (JSONObject) jsonParser.nextValue();
                JSONObject roomidObj = conferenceObj.getJSONObject("conference");
                String roomid = String.valueOf(roomidObj.getInt("RoomId"));
                Log.e(TAG, "onMessageSentResult conf room id is: " + roomid);
                Log.e(TAG, "mEventHandler: " + mEventHandler.toString());
                Handler handler = mEventHandler.getHandler();
                handler.sendMessage(handler.obtainMessage(EventHandler.KEY_MESSAGE_RESULT, EventHandler.KEY_GOT_CONF_ROOMID, 0, roomid));
            } catch (JSONException e) {
                Log.e(TAG, "onMessageSentResult mconf_: " + e.getMessage().toString());
                e.printStackTrace();
            }
        }
    }
}